home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Magnum One
/
Magnum One (Mid-American Digital) (Disc Manufacturing).iso
/
d1
/
coppy33.arc
/
COPPY.C
next >
Wrap
C/C++ Source or Header
|
1989-02-17
|
11KB
|
343 lines
/*
** COPPY -- Copies files from a DIRLIST to floppy disks
** fitting as many files by size as it can.
**
** Thomas A. Lundin
** Graphics Unlimited Inc.
** 3000 Second Street North
** Minneapolis, MN 55411
** (612) 588-7571
**
** Version 1.0 -- Turbo C
** 11/05/87 version 3.0
** 12/30/87 version 3.1 clean up some of the path calls
** 1/06/88 version 3.2 infinite loop bug fixed
** 1/07/88 version 3.3 added -w switch
**
*/
#define TRUE 1
#define FALSE 0
#include <stdio.h>
#include <ctype.h>
#include <fcntl.h>
#include <dos.h>
#include <dir.h>
#include <io.h>
#include <stdlib.h>
#include <sys\stat.h>
char output_file[64]; /* output file name */
char input_file[64]; /* input file name */
char fname_buffer[128]; /* line buffer for gang files */
char *fname_ptr; /* ptr for above */
char *strings; /* where the file names are stored */
char *sptr; /* pointer to that area */
char *data; /* where the file data are stored */
char *dptr; /* pointer to that area */
int driveno; /* dest. drive number */
int fh,fi,fo; /* file handles */
int ctrlc(); /* where CTRL-BREAK goes */
FILE *fl;
char *names[1200];
char s_path[80]; /* source path */
char s_drv[3];
char s_dir[66];
char s_file[9];
char s_ext[5];
char t_path[80]; /* target path */
char t_drv[3];
char t_dir[66];
char t_file[9];
char t_ext[5];
char cur_dir[66];
char s_chdir[66];
char t_chdir[66];
struct dfree freespace;
struct ftime ftod;
struct ffblk fcb;
main(argc, argv)
int argc;
char *argv[];
{
int i, j, k;
long bytesleft;
long maxspace;
long minspace;
long filesize;
long filetotal = 0L;
int length;
int ocount;
int more = TRUE;
int mustsort = TRUE;
int bypass = TRUE;
char name[13];
ctrlbrk(ctrlc);
if(argc < 3)
{
puts("COPPY from HD to FD by largest fit ver.3.3 (c) 1987 Thomas A. Lundin");
puts("usage:\n coppy [d:][\\path\\][filespec] d:[\\path] [-u -w]");
puts("-or-\n coppy @dirlist d:[\\path] [-u -w]");
puts(" 'dirlist' is a file created by redirecting a DIR command");
puts(" -u copies the files in original (unsorted) order");
puts(" -w overrides the bypassing of existing files");
exit(1);
}
for (i = 3; (argc-3) > 0; i++, argc--) { /* process options */
if (strnicmp(argv[i],"-U",2) == 0) {
mustsort = FALSE;
printf("Copy will be in unsorted order\n");
}
else if (strnicmp(argv[i],"-W",2) == 0) {
bypass = FALSE;
printf("Any existing files will be recopied on new diskettes.\n");
}
else {
printf("\nInvalid option: %s\n",argv[i]);
exit(1);
}
}
getcwd(cur_dir,66); /* get current dir */
fnsplit(argv[1],s_drv,s_dir,s_file,s_ext); /* split the names */
fnsplit(argv[2],t_drv,t_dir,t_file,t_ext);
strcpy(s_path,argv[1]);
strcpy(t_chdir,argv[2]);
driveno = (toupper(*t_drv) - '@'); /* drive number */
if ((strings = malloc(25200)) == NULL) { /* space for file names */
printf("Unable to grab string space\n");
exit(1);
}
if ((data = malloc(24576)) == NULL) { /* space for data */
printf("Unable to grab data space\n");
exit(1);
}
/*
The main caller
*/
sptr = strings;
if (*s_file == '@') {
strcpy(name,s_file+1); /* form a file.name */
strcat(name,s_ext);
if ((fl = fopen(name,"r")) == NULL) {
printf("Can't open up %s\n",name);
errorexit(1);
}
i = 0;
while ((fname_ptr = fgets(fname_buffer,128,fl)) != NULL) {
if ((isalnum(*fname_ptr) || ispunct(*fname_ptr))
&& *fname_ptr != '.' && i < 1200) {
make_fn(input_file,fname_ptr);
fi = open(input_file,O_RDONLY);
filesize = filelength(fi);
filetotal += filesize;
sprintf(sptr,"%8.8ld=%s",filesize,input_file);
names[i] = sptr;
_close(fi);
sptr = sptr+strlen(input_file)+9;
*sptr++ = NULL; /* store terminator, bump pointer */
++i; /* bump array index */
}
}
}
else {
for (i = 0; i < 1200; ++i) {
if (i == 0) {
if (findfirst(s_path,&fcb,0) == EOF) {
printf("No files matching %s\n",s_path);
errorexit(1);
}
}
else {
if (findnext(&fcb) == EOF) {
break;
}
}
strcpy(s_path,s_drv); /* what file to read */
strcat(s_path,s_dir);
strcat(s_path,fcb.ff_name);
fi = open(s_path,O_RDONLY);
filesize = filelength(fi);
filetotal += filesize;
sprintf(sptr,"%8.8ld=%s",filesize,fcb.ff_name);
names[i] = sptr;
_close(fi);
sptr = sptr+strlen(fcb.ff_name)+9;
*sptr++ = NULL; /* store terminator, bump pointer */
}
}
if (i >= 1200)
printf("1200-file maximum. Overrun ignored!\n");
if (mustsort)
sort(names,i); /* sort the names in descending size order */
ocount = 0; /* how many files have been copied */
maxspace = 0L; /* disk capacity */
while(more) {
getdfree(driveno,&freespace); /* free space on floppy */
if(freespace.df_sclus == EOF) {
printf("Error in obtaining free space\n");
errorexit(1);
}
bytesleft = (freespace.df_bsec * freespace.df_sclus) * (long )freespace.df_avail;
maxspace = (freespace.df_bsec * freespace.df_sclus) * (long )freespace.df_total;
if (filetotal > 0) {
filesize = filetotal/maxspace; /* # disks required */
minspace = filetotal % maxspace; /* or a fraction thereof */
if (minspace)
++filesize;
if (filesize == 1)
strcpy(t_path,".");
else
strcpy(t_path,"s.");
printf("\n%d files will fit on %ld diskette%s\n",i,filesize,t_path);
printf("\nInsert new disk in drive %c:\nPress any key when ready...\n",driveno + '@');
getch();
printf("\n");
filetotal = 0L;
}
for (k = 0; k < i; ++k) { /* for each file in the list */
if (*(names[k]) == NULL) /* we've already used this one */
continue;
else {
if ((t_chdir[2] & t_chdir[3]) != NULL) { /* output subdir used */
if (access(t_chdir,0) != 0) { /* need to MKDIR on target? */
if (mkdir(t_chdir) == EOF) {
printf("Unable to create subdir %s\n",t_chdir);
errorexit(1);
}
}
}
strcpy(output_file,t_chdir); /* form the output filespec */
strcat(output_file,"\\");
strcat(output_file,names[k]+9);
if (access(output_file,0) == 0) { /* output already exists */
if (bypass == TRUE) {
*(names[k]) = NULL;
++ocount;
printf("%s already exists, and will be bypassed.\n",output_file);
}
else {
printf("%s already exists, but will be copied later.\n",output_file);
}
}
else {
if ((filesize = atol(names[k])) >= bytesleft && mustsort) continue; /* file too large */
else if ((filesize = atol(names[k])) >= bytesleft && !mustsort) break; /* file too large */
else { /* OK to copy */
strcpy(input_file,s_drv); /* what file to read */
strcat(input_file,s_dir);
strcat(input_file,names[k]+9);
if ((fi = open(input_file,O_RDONLY | O_BINARY)) == EOF) {
printf("Unable to open input %s\n",input_file);
errorexit(1);
}
getftime(fi,&ftod); /* read the tod stamp */
if ((fo = open(output_file,O_WRONLY | O_BINARY | O_CREAT, S_IREAD | S_IWRITE)) == EOF) {
printf("Can't open output %s\n",output_file);
errorexit(1);
}
printf("-> %s is %ld bytes\n",names[k]+9,filesize);
while ((length = _read(fi,data,24576)) > NULL)
_write(fo,data,length);
_close(fo);
fo = open(output_file, O_RDONLY); /* open */
setftime(fo,&ftod); /* update time */
_close(fo); /* shut */
_close(fi);
*(names[k]) = NULL; /* don't use this file again */
++ocount; /* output count update */
break;
}
}
}
}
if (ocount >= i) more = FALSE;
if (filesize > maxspace) { /* file size > disk capacity ? */
printf("\n");
for (k = 0; k < i; ++k)
if(*(names[k]) != NULL)
printf("%s must be split up to fit on a disk.\n",names[k]+9);
more = FALSE;
}
if (filesize > bytesleft || k >= i) { /* file size > free space ? */
printf("\nInsert new disk in drive %c:\nPress any key when ready...\n",driveno + '@');
getch();
printf("\n");
}
}
chdir(cur_dir);
exit(0);
}
/*
Make a true file name from a line in the DIRLIST
*/
make_fn(name,line)
char *line, *name;
{
char temp[20];
*name = NULL; /* init name buffer */
stctok(line,temp,20," "); /* get the name */
strcat(name,temp);
strcat(name,".");
stctok(line+9,temp,20," "); /* get the extension */
strcat(name,temp);
return;
}
/*
Copy a string up to a terminator character or length
*/
stctok(from,to,length,term)
char *from,*to,*term;
int length;
{
char c;
/* The following statement will generate a Turbo C WARNING; pay no attention. */
while((c = *from++) && (c != *term) && length--)
*to++ = c;
*to = NULL;
return;
}
ctrlc()
{
chdir(cur_dir);
printf("\nCancelled\n");
return(0);
}
errorexit(n)
int n;
{
chdir(cur_dir);
exit(n);
}